﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using PropertyChanged;
using System.Windows;
using System.Windows.Input;
using DotNet.Utilities.ConsoleHelper;
using NLog;
using WPFPractice.Utils;
using WPFTemplateLib.WpfHelpers;

namespace NLogTester
{
    public partial class MainWindow : Window
    {
        private MainViewModel _vm = new MainViewModel();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = _vm;
        }
    }

    [AddINotifyPropertyChangedInterface]
    public class MainViewModel : MyBindableBase
    {
        #region 成员

        #endregion

        #region Bindable

        /// <summary>
        /// 进程标志
        /// </summary>
        public string ProcessTag { get; set; } = "A";

        /// <summary>
        /// 批量操作的循环次数
        /// </summary>
        public int CyclesNum { get; set; } = 200;

        /// <summary>
        /// 当前循环次数
        /// </summary>
        public int CyclesIndex { get; set; } = 0;

        #endregion

        #region Command

        /// <summary>
        /// 命令：开始执行业务方法
        /// </summary>
        public ICommand StartMethodCmd { get; set; }

        /// <summary>
        /// 命令：开始输出日志
        /// </summary>
        public ICommand StartLogCmd { get; set; }

        /// <summary>
        /// 命令：批量执行业务方法
        /// </summary>
        public ICommand BatchMethodCmd { get; set; }

        /// <summary>
        /// 命令：批量执行业务方法并记录日志
        /// </summary>
        public ICommand BatchLogCmd { get; set; }

        /// <summary>
        /// 命令：指定规则名称来输出日志
        /// </summary>
        public ICommand SpecifyNameToLogCmd { get; set; }

        #endregion

        public MainViewModel()
        {
            SetCommandMethod();

            InitValue();

            //Console.SetOut(new ConsoleWriter(ShowInfo));
        }

        /// <summary>
        /// 数据初始化
        /// </summary>
        private void InitValue()
        {
            ShowInfo("测试 NLog 日志组件");
        }

        /// <summary>
        /// 命令方法赋值(在构造函数中调用)
        /// </summary>
        private void SetCommandMethod()
        {
            StartMethodCmd ??= new RelayCommand(o => true, o =>
            {
                string prefix = DateTime.Now.ToString("HHmmss.ffff");
                ShowInfo($"[{prefix}]开始执行业务方法...");
                Stopwatch sw = Stopwatch.StartNew();
                long sum = GetSum();
                sw.Stop();
                ShowInfo($"[{prefix}]耗时(毫秒)：{sw.ElapsedMilliseconds}");
            });

            StartLogCmd ??= new RelayCommand(o => true, o =>
            {
                string prefix = DateTime.Now.ToString("HHmmss.ffff");
                ShowInfo($"[{prefix}]开始执行业务方法并记录日志...");
                Stopwatch sw = Stopwatch.StartNew();
                long sum = GetSum();
                LogManager.GetCurrentClassLogger().Debug($"计算结果：{sum}");
                sw.Stop();
                ShowInfo($"[{prefix}]耗时(毫秒)：{sw.ElapsedMilliseconds}");
            });

            BatchMethodCmd ??= new RelayCommand(o => CyclesIndex == 0, async o =>
            {
                await Task.Run(() =>
                {
                    try
                    {
                        string prefix = DateTime.Now.ToString("HHmmss.ffff");
                        ShowInfo($"[{prefix}]开始批量执行业务方法[{CyclesNum}]...");
                        Stopwatch sw = Stopwatch.StartNew();
                        for (int i = 0; i < CyclesNum; i++)
                        {
                            CyclesIndex = i + 1;
                            long sum = GetSum();
                        }

                        sw.Stop();
                        ShowInfo($"[{prefix}]平均耗时(毫秒)：{sw.ElapsedMilliseconds / CyclesNum}  总耗时：{sw.Elapsed}");
                    }
                    catch (Exception ex)
                    {
                        ShowInfo($"批量执行业务方法时异常：{ex}");
                    }
                    finally
                    {
                        CyclesIndex = 0;
                    }
                });
            });

            BatchLogCmd ??= new RelayCommand(o => CyclesIndex == 0, async o =>
            {
                await Task.Run(() =>
                {
                    try
                    {
                        string prefix = DateTime.Now.ToString("HHmmss.ffff");
                        ShowInfo($"[{prefix}]开始批量执行业务方法并记录日志[{CyclesNum}]...");
                        Stopwatch sw = Stopwatch.StartNew();
                        for (int i = 0; i < CyclesNum; i++)
                        {
                            CyclesIndex = i + 1;
                            long sum = GetSum();
                            LogManager.GetCurrentClassLogger().Debug($"【{ProcessTag}】计算结果：{sum}");
                        }

                        sw.Stop();
                        ShowInfo($"[{prefix}]平均耗时(毫秒)：{sw.ElapsedMilliseconds / CyclesNum}  总耗时：{sw.Elapsed}");
                    }
                    catch (Exception ex)
                    {
                        ShowInfo($"批量执行业务方法并记录日志时异常：{ex}");
                    }
                    finally
                    {
                        CyclesIndex = 0;
                    }
                });
            });

            SpecifyNameToLogCmd ??= new RelayCommand(o => true, o =>
            {
                string prefix = DateTime.Now.ToString("HHmmss.ffff");
                LogManager.GetLogger("other").Debug($"【{ProcessTag}】{prefix}");
                ShowInfo($"[{prefix}] 已记录到[other]日志");
            });
        }

        #region Method

        /// <summary>
        /// 模拟业务方法（求和）
        /// </summary>
        private long GetSum(int count = 1_0000_0000)
        {
            long sum = 0;
            for (int i = 0; i < count; i++)
            {
                sum += i;
            }

            return sum;
        }

        #endregion
    }
}
